package com.xjrsoft.common.mqtt;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.utils.DatasourceUtil;
import com.xjrsoft.common.utils.IotUtil;
import com.xjrsoft.module.iot.entity.IotDic;

import javax.sql.DataSource;
import java.sql.Struct;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: tzx
 * @Date: 2024/5/6 16:52
 */
public class OpcUaCallBack {

    static List<IotDic> iotDicList;

    static DataSource dataSource;

    static Map<String, Object> cacheChangeMap =  new ConcurrentHashMap<>();

    static Map<String,Long> cacheIntervalMap =  new ConcurrentHashMap<>();

    public OpcUaCallBack(List<IotDic> linkDicList) {

        iotDicList = linkDicList;
    }

    public void onDataChange(Object iotValue, int namespaceIndex, String identifier) {
        Optional<IotDic> currentDic = iotDicList.stream().filter(x -> x.getName().equals(identifier)).findFirst();

        currentDic.ifPresent(iotDic -> {
            Object value = iotValue;


            dataSource = DatasourceUtil.getDataSource(iotDic.getSaveDb());

            if(ObjectUtil.isNotNull(iotDic.getTrans())){
                value = IotUtil.transValue(iotDic, value);
            }

            if(ObjectUtil.isNull(value))
                return;


            //不需要保存
            if (iotDic.getSaveType() == 0) {
            }
            //改变的时候 保存
            else if (iotDic.getSaveType() == 1) {
                if (!value.equals(cacheChangeMap.get(iotDic.getName()))) {
                    insertData(iotDic, value);
                }
            }
            //间隔  保存
            else if (iotDic.getSaveType() == 2) {
                if (cacheIntervalMap.containsKey(iotDic.getName())) {
                    long interval = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() - cacheIntervalMap.get(iotDic.getName());
                    if(interval >= Integer.parseInt(iotDic.getSaveValue())){
                        insertData(iotDic, value);
                    }
                }
                else {
                    insertData(iotDic, value);
                    //缓存此次时间
                    cacheIntervalMap.put(iotDic.getName(), LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
                }
            }
            // 每次都保存
            else {
                insertData(iotDic, value);
            }
        });

    }

    private void insertData(IotDic iotDic, Object value) {
        try {
            String paramSql = "INSERT INTO cy_data (id,var_name,var_type,var_value) VALUES (?,?,?,?);";

            Db.use(dataSource).execute(paramSql, IdUtil.getSnowflakeNextId(), iotDic.getName(), value.getClass().getName(), value);
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}
